from collections import deque
import sys
def get_int():
return int(sys.stdin.readline().strip())
def get_ints():
return map(int,sys.stdin.readline().strip().split())
def get_list():
return list(map(int,sys.stdin.readline().strip().split()))
def get_string():
return sys.stdin.readline().strip()
def dfs(u,n):
q = deque()
visited.clear()
for i in range(n):
par[i] = -1
found = False
q.append(u)
while q and (not found):
node = q.pop()
if (node in visited):
continue
visited.add(node)
for u in adj[node]:
if found:
break
if (u not in visited):
par[u] = node
q.append(u)
elif u!=par[node]:
found=True
while node!=u:
isOnCycle[node]=True
cycle.add(node)
node = par[node]
isOnCycle[u] = True
cycle.add(u)
break
def subSize(u):
val = 1
for v in adj[u]:
if (not isOnCycle[v]):
val+=treeSize(v,u)
return val
def treeSize(root,parent):
q = deque()
q.append(root)
visited.clear()
count= 1
while q:
node = q.popleft()
if node in visited:
continue
visited.add(node)
for u in adj[node]:
if (u in visited) or u==parent:
continue
q.append(u)
count+=1
return count
for _ in range(get_int()):
n = get_int()
lim = n
adj = [[] for _ in range(lim)]
isOnCycle = [False]*lim
cycle = set()
visited = set()
par = [-1]*lim
sub = [-1]*lim
for i in range(n):
adj[i].clear()
isOnCycle[i]=False
sub[i] = -1
cycle.clear()
for _ in range(n):
u,v = get_ints()
u-=1
v-=1
adj[u].append(v)
adj[v].append(u)
dfs(0,n)
ans = n*(n-1)
for u in cycle:
val=subSize(u)
ans = ans - (val*(val-1)//2)
print(ans)
#include <bits/stdc++.h>
using namespace std;
bool x=false;
void cycle(int node,vector<vector<int>>&adj,vector<bool>&vis,stack<int>&q,vector<int>&ans,int&parent,int&d){
vis[node]=true;
q.push(node);
d++;
for(auto it:adj[node]){
if(!vis[it]){
cycle(it,adj,vis,q,ans,node,d);
q.pop();
vis[it]=true;
}
else{
if((it!=parent)&&(!x)){
int xx=it;
stack<int> d=q;
x=true;
while((!d.empty())){
ans.push_back(d.top());
if(d.top()==it) break;
d.pop();
}
break;
}
}
}
}
int main() {
int t;cin>>t;
while(t--){
long long n;cin>>n;
vector<bool> vis(n+1,false);
vector<vector<int>> adj(n+1);
vector<pair<int,int>> edges(n);
for(auto&v:edges) cin>>v.first>>v.second;
for(int j=0;j<n;j++){
int a=edges[j].first,b=edges[j].second;
adj[a].push_back(b);
adj[b].push_back(a);}
vector<int> ans;stack<int> q;
int b=0,k=-1;
cycle(1,adj,vis,q,ans,k,b);x=false;
set<int> s; for(auto it:ans){ s.insert(it);}
for(int j=1;j<=n;j++) adj[j].clear();
for(int j=0;j<n;j++){
int a=edges[j].first,b=edges[j].second;
if(s.find(a)==s.end()||s.find(b)==s.end()){
adj[a].push_back(b);adj[b].push_back(a);
}
}
long long ansx=0;
for(int j=1;j<=n;j++) vis[j]=false;
vector<long long> dx;long long sum=0;
for(int j=1;j<=n;j++){
if(!vis[j]){
int d=0,k=-1;
stack<int> sx;
cycle(j,adj,vis,sx,ans,k,d);x=false;
dx.push_back(d);
sum+=d;
//cout<<d<<" ";
}
}//cout<<endl;
for(auto it:dx){ ansx+=(it*(it-1))/2 + it*(n-it);}
//ansx+=(s.size()*(s.size()-1));
cout<<ansx<<endl;
}
return 0;
}
432D - Prefixes and Suffixes | 486A - Calculating Function |
1373B - 01 Game | 1187A - Stickers and Toys |
313B - Ilya and Queries | 579A - Raising Bacteria |
723A - The New Year Meeting Friends | 302A - Eugeny and Array |
1638B - Odd Swap Sort | 1370C - Number Game |
1206B - Make Product Equal One | 131A - cAPS lOCK |
1635A - Min Or Sum | 474A - Keyboard |
1343A - Candies | 1343C - Alternating Subsequence |
1325A - EhAb AnD gCd | 746A - Compote |
318A - Even Odds | 550B - Preparing Olympiad |
939B - Hamster Farm | 732A - Buy a Shovel |
1220C - Substring Game in the Lesson | 452A - Eevee |
1647B - Madoka and the Elegant Gift | 1408A - Circle Coloring |
766B - Mahmoud and a Triangle | 1618C - Paint the Array |
469A - I Wanna Be the Guy | 1294A - Collecting Coins |